package org.example.ballgamedemo;

import javafx.animation.*;
import javafx.application.Platform;
import javafx.geometry.Bounds;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.util.Duration;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;

import static org.example.ballgamedemo.BouncingBallApp.PREFIX;
import static org.example.ballgamedemo.BouncingBallApp.RECORD_PATH;

public class BallPane extends Pane {
    private ImageView ballImage;
    private double dx = 3, dy = 3;
    private double displayRadius; // 基于实际显示尺寸的半径

    private Rectangle paddle; // 新增反弹板
    private double paddleWidth = 80;
    private double paddleHeight = 15;
    private double paddleSpeed = 10;
    private Timeline timeline;
    private boolean gameOver = false;

    private boolean wasOnPaddle = false;

    private int score = 0;
    private Label scoreLabel;
    private Pane brickContainer = new Pane();
    private List<Rectangle> bricks = new ArrayList<>();

    private Rectangle paddleTop; // 上方反弹板
    private double paddleTopSpeed = 10;
    private String playerTopName; // 上方玩家昵称
    private int scoreTop = 0; // 上方玩家得分
    private Label scoreTopLabel; // 上方得分显示

    private String playerName;

    private boolean leftPressed = false;
    private boolean rightPressed = false;
    private boolean aPressed = false;
    private boolean dPressed = false;

    public BallPane() {



        paddleTop = new Rectangle(0, 0, paddleWidth, paddleHeight);
        paddleTop.setFill(Color.ORANGE);
        getChildren().add(paddleTop);

// 动态定位到窗口顶部
        layoutBoundsProperty().addListener((obs, oldVal, newVal) -> {
            paddleTop.setX((newVal.getWidth() - paddleWidth) / 2);
            paddleTop.setY(20); // 距离顶部20像素
        });

// 上方得分标签
        scoreTopLabel = new Label("得分: 0");
        scoreTopLabel.setStyle("-fx-font-size: 30px; -fx-text-fill: black;");
        getChildren().add(scoreTopLabel);


        Button rankBtn = new Button("排行榜");
        rankBtn.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white;");
        rankBtn.setOnAction(e -> new RankingView().show());

// 动态定位按钮
        layoutBoundsProperty().addListener((obs, oldVal, newVal) -> {
            rankBtn.setLayoutX(newVal.getWidth() - 100);
            rankBtn.setLayoutY(newVal.getHeight() - 40);
        });
        getChildren().add(rankBtn);

        scoreLabel = new Label("得分: 0");
        scoreLabel.setStyle("-fx-font-size: 20px; -fx-text-fill: white; -fx-font-weight: bold;");
        getChildren().add(scoreLabel);

        // 动态定位到右上角
        layoutBoundsProperty().addListener((obs, oldVal, newVal) -> {
            scoreLabel.setLayoutX(newVal.getWidth() - 120); // 距离右边120像素
            scoreLabel.setLayoutY(20); // 距离顶部20像素
        });


        try {
            Image bgImage = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/images/background.jpg")));
            BackgroundSize size = new BackgroundSize(100, 100, true, true, true, true);
            BackgroundImage background = new BackgroundImage(bgImage,
                    BackgroundRepeat.NO_REPEAT,
                    BackgroundRepeat.NO_REPEAT,
                    BackgroundPosition.DEFAULT,
                    size);
            setBackground(new Background(background));
        } catch (NullPointerException e) {
            System.err.println("背景图片加载失败！");
        }


        // 1. 加载图片并初始化 ImageView
        Image ball = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/images/ball.jpg")));
        ballImage = new ImageView(ball);

        // 2. 显式设置 ImageView 的显示尺寸为图片原始尺寸（避免自动缩放）
        ballImage.setFitWidth(ball.getWidth());
        ballImage.setFitHeight(ball.getHeight());

        // 3. 计算实际显示尺寸的半径
        displayRadius = Math.min(ballImage.getFitWidth(), ballImage.getFitHeight()) / 2;

        // 4. 设置圆形裁剪（基于显示尺寸）
        Circle clip = new Circle();
        clip.centerXProperty().bind(ballImage.fitWidthProperty().divide(2));
        clip.centerYProperty().bind(ballImage.fitHeightProperty().divide(2));
        clip.setRadius(displayRadius);
        ballImage.setClip(clip);

        // 5. 设置初始位置（居中）
        ballImage.setLayoutX(300 - ballImage.getFitWidth() / 2);
        ballImage.setLayoutY(200 - ballImage.getFitHeight() / 2);
        getChildren().add(ballImage);

        // 6. 动画逻辑
         timeline = new Timeline(
                new KeyFrame(Duration.millis(20), e -> moveBall())
        );
        timeline.setCycleCount(Timeline.INDEFINITE);
        //timeline.play();

        paddle = new Rectangle(0, 0, paddleWidth, paddleHeight);
        paddle.setFill(Color.BLACK);
        getChildren().add(paddle);

// 添加布局监听器动态设置位置
        layoutBoundsProperty().addListener((obs, oldVal, newVal) -> {
            paddle.setX((newVal.getWidth() - paddleWidth) / 2);
            paddle.setY(newVal.getHeight() - 20); // 距离底部50像素
        });

        // 添加键盘监听
        setOnKeyPressed(e -> handleKeyPress(e));
        setOnKeyReleased(e -> handleKeyRelease(e));
    }

    public void startGame() {
        timeline.play();
    }
    public void showStartButton() {
        Button startBtn = new Button("开始游戏");
        startBtn.setStyle("-fx-font-size: 24px; -fx-background-color: #AADDFF; -fx-text-fill: white;");

        // 动态居中定位
        layoutBoundsProperty().addListener((obs, oldVal, newVal) -> {
            startBtn.setLayoutX((newVal.getWidth() - startBtn.getWidth()) / 2);
            startBtn.setLayoutY((newVal.getHeight() - startBtn.getHeight()) / 2);
        });

        startBtn.setOnAction(e -> {
            startGame(); // 启动游戏
            getChildren().remove(startBtn); // 移除按钮
            requestFocus(); // 重新获取焦点以响应键盘事件
        });
        getChildren().add(startBtn);
    }
    public void setPlayerName(String playerName1, String playerTopName) {
        this.playerName=playerName1;
        this.playerTopName=playerTopName;
    }

    /*private void initBricks()  {
        brick.getStyleClass().add("brick");
// 场景加载CSS
        scene().getStylesheets().add(getClass().getResource("/styles/game.css").toExternalForm());
        int rows = 3;
        int cols = 12;
        double brickWidth = 50;
        double brickHeight = 20;
        double spacing = 2;

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                brick = new Rectangle(
                        j * (brickWidth + spacing),
                        i * (brickHeight + spacing) + 50, // 留出顶部空间
                        brickWidth,
                        brickHeight
                );
                brick.setFill(Color.hsb(i * 60, 0.7, 0.8)); // 渐变色
                brick.setArcWidth(5); // 圆角效果[3](@ref)
                brick.setArcHeight(5);
                bricks.add(brick);
            }
        }
        brickContainer.getChildren().addAll(bricks);
        getChildren().add(0, brickContainer); // 置于底层
    }*/
    private void saveScore() {
        try {
            List<String> records = Files.readAllLines(Paths.get(PREFIX + RECORD_PATH));
            Map<String, Integer> scoreMap = new HashMap<>();

            // 解析现有记录
            for (String record : records) {
                String[] parts = record.split(" ");
                if (parts.length >= 2) {
                    scoreMap.put(parts[0], Math.max(Integer.parseInt(parts[1]),
                            scoreMap.getOrDefault(parts[0], 0)));
                }

                String name = parts[0];
                int score = Integer.parseInt(parts[1]);
                scoreMap.put(name, Math.max(score, scoreMap.getOrDefault(name, 0)));
            }

            // 更新当前玩家分数
            scoreMap.put(playerName, Math.max(score, scoreMap.getOrDefault(playerName, 0)));
            scoreMap.put(playerTopName, Math.max(scoreTop, scoreMap.getOrDefault(playerTopName, 0)));
            // 转换并排序
            List<String> sortedRecords = scoreMap.entrySet().stream()
                    .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
                    .limit(10)
                    .map(entry -> entry.getKey() + " " + entry.getValue())
                    .collect(Collectors.toList());

            // 写回文件
            Files.write(Paths.get(PREFIX + RECORD_PATH), sortedRecords);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void showGameOverDialog() {
        Platform.runLater(() -> {
            Alert alert = new Alert(Alert.AlertType.INFORMATION);
            alert.setTitle("游戏结束");
            alert.setHeaderText(null);
            alert.setContentText("曼巴精神永不放弃！再来一局？");
// 添加重新开始按钮
            ButtonType restartButton = new ButtonType("重新开始");
            ButtonType exitButton = new ButtonType("退出");
            alert.getButtonTypes().setAll(restartButton, exitButton);

            alert.showAndWait().ifPresent(buttonType -> {
                if (buttonType == restartButton) {
                    saveScore();
                    resetGame();
                } else {
                    saveScore();
                    System.exit(0);
                }
            });
        });
    }

    private void resetGame() {
        // 重置游戏状态
        gameOver = false;
        ballImage.setLayoutX(200 - ballImage.getFitWidth() / 2);
        ballImage.setLayoutY(150 - ballImage.getFitHeight() / 2);
        dx = 3;
        dy = 3;
        timeline.play();
        score = 0;
        scoreLabel.setText("得分: 0");
        scoreTop = 0; // 新增：重置上方玩家分数
        scoreTopLabel.setText("得分: 0"); // 更新显示
    }

    private void moveBall() {

        if (gameOver) return;
        Bounds bounds = getBoundsInLocal();

        if (leftPressed) {
            paddle.setX(Math.max(bounds.getMinX(), paddle.getX() - paddleSpeed));
        }
        if (rightPressed) {
            paddle.setX(Math.min(bounds.getMaxX() - paddleWidth, paddle.getX() + paddleSpeed));
        }

        // 处理上方玩家控制
        if (aPressed) {
            paddleTop.setX(Math.max(bounds.getMinX(), paddleTop.getX() - paddleTopSpeed));
        }
        if (dPressed) {
            paddleTop.setX(Math.min(bounds.getMaxX() - paddleWidth, paddleTop.getX() + paddleTopSpeed));
        }

        double centerX = ballImage.getLayoutX() + ballImage.getFitWidth() / 2;
        double centerY = ballImage.getLayoutY() + ballImage.getFitHeight() / 2;
        boolean hitPaddleTop = (centerY - displayRadius <= paddleTop.getY() + paddleHeight) &&
                (centerX >= paddleTop.getX()) &&
                (centerX <= paddleTop.getX() + paddleWidth);
        boolean hitTop = (centerY - displayRadius) <= bounds.getMinY();

        if (hitPaddleTop) {
            scoreTop += 10;
            scoreTopLabel.setText("得分: " + scoreTop);
            dy *= -1;

            // 添加反弹角度变化
            double hitPosRatio = (centerX - paddleTop.getX()) / paddleWidth;
            dx = (hitPosRatio - 0.5) * 10;
        } else if (hitTop) { // 新增：顶部碰撞未接球时结束
            gameOver = true;
            timeline.stop();
            showGameOverDialog();
            return;
        }

        Iterator<Rectangle> iterator = bricks.iterator();
        while (iterator.hasNext()) {
            Rectangle brick = iterator.next();
            Bounds brickBounds = brick.getBoundsInParent();

            if (brickBounds.intersects(
                    ballImage.getLayoutX() - displayRadius,
                    ballImage.getLayoutY() - displayRadius,
                    displayRadius * 2,
                    displayRadius * 2)) {

                // 移除砖块和碰撞处理
                brickContainer.getChildren().remove(brick);
                iterator.remove();
                score += 15;
                scoreLabel.setText("得分: " + score);

                // 碰撞方向判断
                double ballCenterX = ballImage.getLayoutX() + displayRadius;
                boolean hitVertical = (ballCenterX < brickBounds.getMinX()) ||
                        (ballCenterX > brickBounds.getMaxX());

                if (hitVertical) {
                    dx *= -1;
                } else {
                    dy *= -1;
                }
                break; // 每次只处理一个碰撞
            }
        }


        centerX = ballImage.getLayoutX() + ballImage.getFitWidth() / 2;
        centerY = ballImage.getLayoutY() + ballImage.getFitHeight() / 2;

        boolean hitPaddle = (centerY + displayRadius >= paddle.getY()) &&
                (centerX + displayRadius >= paddle.getX()) &&            // 小球右侧接触弹板左侧
                (centerX - displayRadius <= paddle.getX() + paddleWidth);


        if (hitPaddle) {
            if (!wasOnPaddle) {
                score += 10;
                scoreLabel.setText("得分: " + score);
            }
            wasOnPaddle = true;
            dy *= -1;

            double hitPosRatio = (centerX - paddle.getX()) / paddleWidth;
            dx = (hitPosRatio - 0.5) * 10;
        } else {
            wasOnPaddle = false;
        }
        boolean hitBottom = (centerY + displayRadius) >= (bounds.getMaxY() - 1);
        if (hitBottom) {
            gameOver = true;
            timeline.stop();
            showGameOverDialog();
            return;
        }


        // 碰撞检测（基于实际显示半径）
        boolean hitLeft = (centerX - displayRadius) <= bounds.getMinX();
        boolean hitRight = (centerX + displayRadius) >= bounds.getMaxX();


        if (hitLeft || hitRight) dx *= -1;
        if (hitTop) dy *= -1;

        ballImage.setLayoutX(ballImage.getLayoutX() + dx);
        ballImage.setLayoutY(ballImage.getLayoutY() + dy);
    }

    private void handleKeyPress(KeyEvent e) {
        Bounds bounds = getBoundsInLocal();
        switch (e.getCode()) {
            case LEFT -> leftPressed = true;
            case RIGHT -> rightPressed = true;
            case A -> aPressed = true;
            case D -> dPressed = true;
        }
    }

    private void handleKeyRelease(KeyEvent e) {
        switch (e.getCode()) {
            case LEFT -> leftPressed = false;
            case RIGHT -> rightPressed = false;
            case A -> aPressed = false;
            case D -> dPressed = false;
        }
        // 左键控制
        /*if (e.getCode() == KeyCode.LEFT) {
            double newX = paddle.getX() - paddleSpeed;
            if (newX >= bounds.getMinX()) { // 左边界检测
                paddle.setX(newX);
            }
        }
        // 右键控制
        else if (e.getCode() == KeyCode.RIGHT) {
            double newX = paddle.getX() + paddleSpeed;
            if (newX + paddleWidth <= bounds.getMaxX()) { // 右边界检测
                paddle.setX(newX);
            }
        }

        if (e.getCode() == KeyCode.A) {
            paddleTop.setX(Math.max(bounds.getMinX(), paddleTop.getX() - paddleTopSpeed));
        } else if (e.getCode() == KeyCode.D) {
            paddleTop.setX(Math.min(bounds.getMaxX() - paddleWidth, paddleTop.getX() + paddleTopSpeed));
        }*/
    }
}